package com.learning.thread.base.threadlocal;

import java.util.Random;

/**
 * ClassName: CustomThread
 * Description: ThreadLocal 轻松实现线程范围内的数据共享
 *
 * <p>
 * Date: 2014-6-29 8:00 【需求编号】
 *
 * @author Sam Sho
 * @version V1.0.0
 */
public class ThreadLocalShareData {
    /**
     * 传递数据的容器，map的key为线程对象
     * 使用 ThreadLocal 代替 Map
     */
    private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();

    /**
     * 有几个线程就会有几份数据：
     * 多个相对访问同一个线程的数据是一样的
     * 不同线程的数据是不同的
     *
     * @param args
     */
    public static void main(String[] args) {
        new Thread(new InThread(), "InThread0: ").start();
        new Thread(new InThread(), "InThread1: ").start();
    }


    static class InThread implements Runnable {

        @Override
        public void run() {
            int data = new Random().nextInt();
            //把数据放入MAP
            threadLocal.set(data);

            System.out.println(Thread.currentThread().getName() + " has put data :" + data);

            // 说ThreadLocal使得各线程能够保持各自独立的一个对象，并不是通过ThreadLocal.set()来实现的，而是通过每个线程中的new 对象 的操作来创建的对象
            new ObjectA().get();
            new ObjectB().get();
            // 显示调用 ThreadLocalMap.remove方法清除线程共享变量
            threadLocal.remove();
        }
    }


    /**
     * 模块A
     */
    static class ObjectA {
        public void get() {
            //从线程获取数据
            int data = threadLocal.get();
            System.out.println("ObjectA from " + Thread.currentThread().getName() + " get data :" + data);
        }
    }

    /**
     * 模块B
     */
    static class ObjectB {
        public void get() {
            //从线程获取数据
            int data = threadLocal.get();
            System.out.println("ObjectB from " + Thread.currentThread().getName() + " get data :" + data);
        }
    }

}
